package optimizacion;

import java.util.ArrayList;
import java.util.Random;

/**
 * Clase que extiende de la clase padre Gen con genotipo Boolean (0,1) y fenotipo double
 * Calulamos su longitud mediante una funcion de FuncionesAuxiliares
 */
public class Gen{
	
	 protected int[] genotipo;
	 public double fenotipo;    
	 protected int longitud;
	
	public Gen(int longitud){
        this.longitud = longitud;
        this.genotipo = new int[longitud];
	}
	
	public Gen(){
			
	}


	public Double calcularFenotipo(double [][] d, double [][] f) {		
		fenotipo = 0;
		
		for (int i=0; i<longitud; i++)
			for (int j=0; j<longitud; j++){
				/*double fIJ = f[i][j];
				int genI = genotipo[i];
				int genJ = genotipo[j];
				double dIJ = d[genotipo[i]][genotipo[j]];
				double suma = f[i][j] * d[genotipo[i]][genotipo[j]];*/
				
				fenotipo += f[i][j] * d[genotipo[i]][genotipo[j]];
				
			}
				
		
		return fenotipo;
	}
	
	public void inicializar(int valorSemilla, boolean semilla){
        
		for (int i=0; i<longitud; i++){
        	genotipo[i] = i;
        }         
        
        barajar(valorSemilla, semilla);
    }
    
	public void barajar(int valorSemilla, boolean semilla){
    	Random r;
    	
    	if (semilla)  r = new Random(valorSemilla);
    	else  r= new Random();
    	
        for (int i=longitud; i>1; i--){
        	int tmp = genotipo[i-1];
        	int radix = r.nextInt(longitud);
        	genotipo[i-1] = genotipo[radix];
        	genotipo[radix] = tmp;
        }         
    }
  
       
    public Gen clone (){
    	Gen gen = new Gen();
    	gen.genotipo = this.genotipo.clone();
    	gen.fenotipo = this.fenotipo;
    	gen.longitud = this.longitud;
    	return gen;    		
    }
    
    
    
	public int[] getGenotipo() {
		return genotipo;
	}

	public void setGenotipo(int[] genotipo) {
		this.genotipo = genotipo.clone();
		
	}

	public double getFenotipo() {
		return fenotipo;
	}

	public void setFenotipo(double fenotipo) {
		this.fenotipo = fenotipo;
	}

	public int getLongitud() {
		return longitud;
	}

	public void setLongitud(int longitud) {
		this.longitud = longitud;
	}

	public void setGenotipo(int[] puntosCruce, ArrayList<Integer> arrayList) {
		for (int i = 0; i < puntosCruce.length; i++){
			genotipo[puntosCruce[i]] = arrayList.get(i);
		}
	}

	public void aumentarGenotipoMas1() {
		for (int i = 0; i < longitud; i++){
			genotipo[i] = (genotipo[i] + 1) % longitud;
		}
	}

	public void setGenotipo(int posInicialRandom, int numPermutaciones, ArrayList<Integer> arrayList) {
		for (int i = 0; i < numPermutaciones; i++){
			genotipo[i+posInicialRandom] = arrayList.get(i);
		}
	}    
    
}